/*
 * Licensed to the Tai Ping Jin Ke
 *
 * Copyright (c) 2022 .
 * All rights reserved.
 * 项目名称：太平金科-基础组件封装层-SpringBoot组件封装-缺省实现
 * 版权说明：本软件属太平金融科技服务(上海)有限公司所有，在未获得太平金融科技服务(上海)有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.taipingframework.boot.web.autoconfigure;

import com.taipingframework.boot.web.properties.Swagger2Property;
import com.taipingframework.boot.web.support.BaseUrlBuilder;
import com.taipingframework.utility.constant.ApplicationConstant;
import com.taipingframework.utility.extend.IpAddressHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration;

@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@EnableSwagger2
@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(Swagger2DocumentationConfiguration.class)
public class Swagger2AutoConfiguration {

    /**
     * 对 开发环境、测试环境放、验收环境 开放swagger-ui，若是 生产环境 则禁止访问
     */
    private static final Profiles PROFILES = Profiles.of("dev", "test", "uat"); // "prod"

    /**
     * swagger2文档配置
     */
    @Bean
    @ConfigurationProperties(prefix = "application.swagger")
    public Swagger2Property swagger2Property() {
        return new Swagger2Property();
    }

    /**
     * swagger2文档配置
     */
    @Bean
    public Docket projectRestApi(Swagger2Property swagger2Property,
                                 Environment env,
                                 ApplicationContext applicationContext) {
        // 对 开发环境、测试环境放、验收环境 开放swagger-ui，若是 生产环境 则禁止访问
        boolean enableSwaggerUI = env.acceptsProfiles(PROFILES) && swagger2Property.getEnable();
        ApiInfo apiInfo = apiInfo(swagger2Property, applicationContext);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo)
                .groupName(swagger2Property.getGroupName())
                .host(IpAddressHelper.getServerIp())
                .pathMapping("/")
                .select()
                .apis(RequestHandlerSelectors.any()) // RequestHandlerSelectors.basePackage(swagger2Property.getBasePackage())
                .paths(PathSelectors.any()) // PathSelectors.ant("/api/admin/**")
                .build()
                .enable(enableSwaggerUI);
    }

    /**
     * Api Documentation
     */
    private ApiInfo apiInfo(Swagger2Property swagger2Prop, ApplicationContext applicationContext) {
        ApiInfoBuilder apiInfoBuilder = new ApiInfoBuilder()
                .title(swagger2Prop.getTitle())
                .description(swagger2Prop.getDescription())
                .version(swagger2Prop.getVersion())
                .termsOfServiceUrl(getBaseUrl(applicationContext));

        if (!StringUtils.isAnyEmpty(swagger2Prop.getContactName(), swagger2Prop.getContactUrl(), swagger2Prop.getContactEmail())) {
            apiInfoBuilder.contact(new Contact(swagger2Prop.getContactName(), swagger2Prop.getContactUrl(), swagger2Prop.getContactEmail()));
        }

        if (!StringUtils.isAnyEmpty(swagger2Prop.getLicense(), swagger2Prop.getLicenseUrl())) {
            apiInfoBuilder.license(swagger2Prop.getLicense()).licenseUrl(swagger2Prop.getLicenseUrl());
        }

        return apiInfoBuilder.build();
    }

    private String getBaseUrl(ApplicationContext applicationContext) {
        if (applicationContext instanceof ServletWebServerApplicationContext) {
            return BaseUrlBuilder.createBaseUrlAboutSpringWeb(applicationContext, (serverProperties) -> serverProperties.getServlet().getContextPath());
        } else {
            return ApplicationConstant.LOCAL_URL;
        }
    }

}
